﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.EntityClient;

namespace Net.Chirash.Twitter.TwitterDatabase.Statistics
{
    public class TwitterStatistics
    {
        private TwitterCachingConnection conn;

        public TwitterStatistics(TwitterCachingConnection conn)
        {
            this.conn = conn;
        }

        public IEnumerable<ValueContainer> GetStatusCount(StatusStatCountArgs args)
        {
            var context = conn.Entities;

            Func<Status, object> selector = null;
            switch (args.GroupBy)
            {
                case StatusStatCountArgs.StatGrouping.Day:
                    selector = new Func<Status, object>((sta) => (long)sta.CreatedAt.Day);
                    break;
                case StatusStatCountArgs.StatGrouping.Hour:
                    selector = new Func<Status, object>((sta) => (long)sta.CreatedAt.Hour);
                    break;
                case StatusStatCountArgs.StatGrouping.Month:
                    selector = new Func<Status, object>((sta) => (long)sta.CreatedAt.Month);
                    break;
                case StatusStatCountArgs.StatGrouping.UserID:
                    selector = new Func<Status, object>((sta) => (long)sta.UserID);
                    break;
                case StatusStatCountArgs.StatGrouping.Year:
                    selector = new Func<Status, object>((sta) => (long)sta.CreatedAt.Year);
                    break;
                default:
                    throw new InvalidOperationException("groupbyで対応してないフラグが立ってます");
            }

            var preq = from sta in context.Statuses
                       select sta;

            if (args.UserID > -1)
            {
                preq = preq.Where((sta) => sta.UserID == args.UserID);
            }
            if (args.year > -1)
            {
                preq = preq.Where((sta) => sta.CreatedAt.Year == args.year);
            }
            if (args.month > -1)
            {
                preq = preq.Where((sta) => sta.CreatedAt.Month == args.month);
            }
            if (args.day > -1)
            {
                preq = preq.Where((sta) => sta.CreatedAt.Day == args.day);
            }
            if (args.hour > -1)
            {
                preq = preq.Where((sta) => sta.CreatedAt.Hour == args.hour);
            }

            var q = preq
                    .GroupBy(selector)
                    .Select((gr) => new ValueContainer() { Index = (long)gr.Key, Value = gr.Count() });

            return q.ToArray();

        }

    }
    #region public class

    public class ValueContainer : TwitterData
    {
        public ValueContainer()
        { }

        public ValueContainer(long index, long value)
        {
            this.Index = index;
            this.Value = value;
        }

        public long Index { get; set; }
        public long Value { get; set; }
    }

    /// <summary>
    /// TwitterCaching.GetStatusStatisticsCount()の抽出条件を指定するクラス。
    /// </summary>
    public class StatusStatCountArgs
    {
        /// <summary>
        /// 発言された年を指定します。使用されない場合は負値を指定してください
        /// </summary>
        public int year;
        /// <summary>
        /// 発言された月を指定します。使用されない場合は負値を指定してください
        /// </summary>
        public int month;
        /// <summary>
        /// 発言された日を指定します。使用されない場合は負値を指定してください
        /// </summary>
        public int day;
        /// <summary>
        /// 発言された時刻を指定します。使用されない場合は負値を指定してください
        /// </summary>
        public int hour;
        /// <summary>
        /// 抽出するUserIDをひとつ指定します。すべてのUserIDを指定する場合は負値を指定してください
        /// </summary>
        public long UserID;

        /// <summary>
        /// GroupByされる項目を指定します
        /// </summary>
        public StatGrouping GroupBy;

        public StatusStatCountArgs()
        {
            year = -1;
            month = -1;
            day = -1;
            hour = -1;
            UserID = -1;
        }

        [FlagsAttribute()]
        public enum StatGrouping : int
        {
            UserID = 1,
            Year = 2,
            Month = 4,
            Day = 8,
            Hour = 16
        };
    }

    #endregion

}
